package com.maimao.kill.service;

import cn.hutool.core.util.ObjectUtil;
import cn.hutool.db.Page;
import com.github.pagehelper.PageHelper;
import com.google.common.collect.Lists;
import com.maimao.core.exception.MaiMaoDaoException;
import com.maimao.core.model.resp.PageResult;
import com.maimao.core.model.resp.Result;
import com.maimao.kill.controller.KillApplyController;
import com.maimao.kill.mapper.ActivityMapper;
import com.maimao.kill.mapper.ScheduleMapper;
import com.maimao.model.common.ScheduleStatusInput;
import com.maimao.model.common.StatusInput;
import com.maimao.model.kill.Activity;
import com.maimao.model.kill.Schedule;
import com.maimao.model.kill.input.ScheduleInput;
import com.maimao.model.kill.input.ScheduleTemplate;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDate;
import java.time.LocalDateTime;
import java.util.List;

import static com.maimao.core.constant.Constants.ONE;
import static com.maimao.core.constant.Constants.ZERO;

/**
 * @author MaoLin Wang
 * @date 2021/4/7 8:52 下午
 */
@Slf4j
@Service
public class ScheduleService {

    @Autowired
    private ScheduleMapper scheduleMapper;

    @Autowired
    private ActivityMapper activityMapper;


    public PageResult<Schedule> list(ScheduleInput scheduleInput) {
        PageHelper.startPage(scheduleInput.getPage(), scheduleInput.getSize());
        List<Schedule> schedules = scheduleMapper.selectByParams(scheduleInput);
        PageResult<Schedule> pageResult = new PageResult<>(schedules);
        return pageResult;

    }

    /**
     * 根据模板批量创建排期
     *
     * @param template 目标
     * @param by       创建方式
     */
    @Transactional(rollbackFor = MaiMaoDaoException.class)
    public boolean addByTemplate(ScheduleTemplate template, Integer by) {
        Activity activity = activityMapper.selectById(template.getActivityId());
        if (activity == null) {
            return false;
        }
        Integer cycle = template.getCycle();
        Integer dayStartHour = template.getDayStartHour();
        Integer dayEndHour = template.getDayEndHour();

        //单日总时间
        int totalHour = dayEndHour - dayStartHour;
        int diff = totalHour % cycle;

        if (diff > 0) {
            // 不可整期排，则去掉多余的小时数 如 (total=9)%(cycle=7)=2 结束时间去掉两小时
            dayEndHour -= diff;
        }

        List<Schedule> scheduleList = Lists.newArrayList();
        //排期开始日期
        LocalDate startDate = template.getStartTime();
        for (int i = 0; i < template.getDay(); i++) {
            LocalDate currentDate = startDate.plusDays(i);
            //每日开始时间
            LocalDateTime dayStart = LocalDateTime.of(currentDate.getYear(), currentDate.getMonth(), currentDate.getDayOfMonth(), dayStartHour, ZERO);

            Schedule schedule;
            //当日的排期
            for (int j = dayStartHour; j <= (dayEndHour - cycle); j += cycle) {
                schedule = new Schedule();
                schedule.setActivityId(template.getActivityId());
                schedule.setBy(by);
                schedule.setEnabled(activity.getStatus());
                schedule.setMaxCount(template.getCount());
                schedule.setUsedCount(ZERO);

                //每期开始时间
                LocalDateTime perStart = dayStart.plusHours(j - dayStartHour);
                schedule.setStartTime(perStart);
                schedule.setEndTime(perStart.plusHours(cycle));
                List<Schedule> existData = scheduleMapper.queryExist(schedule.getStartTime(), schedule.getEndTime());
                if (ObjectUtil.isEmpty(existData)){
                    scheduleList.add(schedule);
                }
            }
        }
        if (ObjectUtil.isNotEmpty(scheduleList)) {
            scheduleMapper.saveBatch(scheduleList);
            log.info("生成排期成功，活动id:{},活动名：{},新生成排期数量:{}", activity.getId(), activity.getName(), scheduleList.size());
        }
        return true;
    }

    /**
     * 后期改成批量 这里省时间就先单个的
     *
     * @param input
     */
    public Result updateStatus(ScheduleStatusInput input) {
        if (input.getStatus().equals(ONE)) {
            //开启
            Activity activity = activityMapper.selectById(input.getActivityId());
            if (activity == null) {
                return Result.notValid("所在活动不存在，无法更改");
            }
            if (activity.getStatus().equals(ZERO)) {
                return Result.notValid("目标活动尚未开始或已停止，不可开启排期");
            }
            scheduleMapper.updateById(Schedule.builder().id(input.getId()).enabled(ONE).build());
        } else {
            //停止
            scheduleMapper.updateById(Schedule.builder().id(input.getId()).enabled(ZERO).build());

        }
        return Result.ok(input.getStatus().equals(ONE) ? "排期已开启" : "已停止排期");
    }

    public PageResult<Schedule> usableList(ScheduleInput input) {
        PageHelper.startPage(input.getPage(), input.getSize());
        LocalDateTime startDate = LocalDateTime.now().plusDays(0);
        // TODO 测试完删注释
       /* if (LocalDateTime.now().getHour() >= KillApplyController.APPLY_HOUR_LIMIT) {
            //超过当日15点，则只能报名后天以后的排期
            startDate = startDate.plusDays(1);
        }*/
        startDate = startDate.withHour(0).withMinute(0).withSecond(0);
        input.setFromTime(startDate);
        input.setEnabled(ONE);
        List<Schedule> schedules = scheduleMapper.selectByParams(input);
        return new PageResult<>(schedules);
    }

    public List<Schedule> selectBatch(List<Long> scheduleIds) {
        return scheduleMapper.selectBatchIds(scheduleIds);
    }

    /**
     * 根据开始时间范围查询排期
     * @param fromTime 闭区间
     * @param endTime 开区间
     */
    public List<Schedule> queryByStarTimeBetween(LocalDateTime fromTime, LocalDateTime endTime) {
        return scheduleMapper.queryByStarTimeBetween(fromTime,endTime);
    }
}
